package com.yc.resfoods.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.bean.Resfood;
import com.yc.resfoods.biz.ResfoodBiz;
import com.yc.web.model.PageBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @ClassName ResfoodController
 * @since: 2023/8/20 16:13
 * @auth: kirito
 * @description:
 **/
@RestController
@RequestMapping("resfood")
@Slf4j
@Api(tags = "菜品管理")
public class ResfoodController {
    @Autowired
    private ResfoodBiz resfoodBiz;

    //集合set 存线程
    public Set<Thread>  set = new HashSet<>();

    @RequestMapping(value = "findById/{fid}",method = {RequestMethod.GET,RequestMethod.POST})
    @ApiOperation(value = "根据菜品编号查询操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fid", value = "菜品号", required = true,dataTypeClass = Integer.class)
    })
    public Map<String, Object> findById(@PathVariable Integer fid) {
        Map<String, Object> map = new HashMap<>();
        Resfood resfood = null;
        try {
            resfood = this.resfoodBiz.findById(fid);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", 0);
            map.put("msg", e.getCause());
            return map;
        }
        map.put("code", 1);
        map.put("obj", resfood);
        return map;
    }

    @GetMapping("findAll")
    @ApiOperation(value = "查询所有的菜品")
//    @SentinelResource(value = "findAll",fallback = "exceptionFallback")
    public Map<String, Object> findAll() {
//        int flag = 1;
//        if (flag == 1) {
//            throw  new RuntimeException("业务异常：查找出所有异常");
//        }
//        Thread thread = Thread.currentThread();
//        set.add(thread);
//        log.info("线程数为：" + set.size() + ",当前线程编号: " + thread.getId());

//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        Map<String, Object> map = new HashMap<>();
        List<Resfood> list = null;
        try {
            list = this.resfoodBiz.findAll();
        } catch (Exception e) {
            map.put("code", 1);
            map.put("msg", e.getCause());
            return map;
        }
        map.put("code", 1);
        map.put("obj", list);
        return map;
    }

//    @SentinelResource(value = "hotkey-page", blockHandler = "handleBlock")
    @RequestMapping(value = "findByPage", method = {RequestMethod.GET, RequestMethod.POST})
    @ApiOperation(value = "分页查询操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageno", value = "页号", required = true, dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "pagesize", value = "每页记录数", required = true, dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "sortby", value = "排序列", required = true, dataTypeClass = String.class),
            @ApiImplicitParam(name = "sort", value = "排序方式", required = true, dataTypeClass = String.class)
    })
    public Map<String, Object> findByPage(@RequestParam int pageno, @RequestParam int pagesize, @RequestParam String sortby, @RequestParam String sort) {
        Map<String, Object> map = new HashMap<>();
        Page<Resfood> page = null;
        try {
            page = this.resfoodBiz.findByPage(pageno, pagesize, sortby, sort);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("code", 1);
            map.put("msg", e.getCause());
            return map;
        }
        map.put("code", 1);
        //包装一个web model 用于在界面显示结果
        PageBean pageBean = new PageBean();
        pageBean.setPageno(pageno);
        pageBean.setSort(sort);
        pageBean.setSortby(sortby);
        pageBean.setTotal(page.getTotal());
        pageBean.setDataset(page.getRecords());
        //其他的分页数据  计算总页数
        long totalPages = page.getTotal() % pageBean.getPagesize() == 0 ?
                page.getTotal() / pageBean.getPagesize() : pageBean.getPagesize() + 1;
        pageBean.setTotalpages((int) totalPages);
        //上一页页号计算
        if (pageBean.getPageno() <= 1) {
            pageBean.setPre(1);
        } else {
            pageBean.setPre(pageBean.getPageno() - 1);
        }
        //下一页
        if (pageBean.getPageno() == totalPages) {
            pageBean.setNext((int) totalPages);
        } else {
            pageBean.setNext(pageBean.getPageno() + 1);
        }
        map.put("data", pageBean);
        return map;
    }
    //限流发生的回调处理方法  流控异常的类型，由sentinel捕获注入
    private Map<String, Object> handleBlock(
            @RequestParam int pageno,@RequestParam int pagesize,
            @RequestParam String sortby, @RequestParam String sort,
            BlockException e
    ){
        e.printStackTrace();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "资源："+e.getRuleLimitApp()+"：被限流，规则为："+e.getRule().toString()+",异常信息:"+e.getMessage());
        return map;
    }

    private Map<String, Object> exceptionFallback(Throwable t){
        t.printStackTrace();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("msg", "resource is under exception. cause as following: "+ t.getCause());
        return map;
    }
}
